﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using StockholmsStad.Utilities.Exceptions;

namespace StockholmsStad.ServiceModel.Interfaces
{
    /// <summary>
    /// Servicekontrakt för windows klient tjänsterna
    /// </summary>
    [ServiceContract]
    public interface IWinService
    {
        /// <summary>
        /// Operationskontrakt som hämtar alla ceremonispråk.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista av typen <see cref="ValueIdPair"/> med ceremonispråk eller tom lista om inga språk finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<ValueIdPair> GetCeremonyLanguages(User user);

        /// <summary>
        /// Operationskontrakt som hämtar alla certifikatspråk.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista av typen <see cref="ValueIdPair"/> med certifikatspråk eller tom lista om inga språk finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<ValueIdPair> GetCertificateLanguages(User user);

        /// <summary>
        /// Operationskontrakt för att hämta aktuellt standardspråk
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>Standardspråket eller tom sträng om inget sådant finns angivet</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        ValueIdPair GetDefaultLanguage(User user);

        /// <summary>
        /// Operationskontrakt som hämtar alla hjälpmedel.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista av typen <see cref="ValueIdPair"/> med hjälpmedel eller tom lista om inga hjälpmedel finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<ValueIdPair> GetCeremonySpecialNeeds(User user);

        /// <summary>
        /// Operationskontrakt som hämtar alla ceremonityper.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista av typen <see cref="ValueIdPair"/> med certifikatspråk eller tom lista om inga språk finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<ValueIdPair> GetCeremonyTypes(User user);


        /// <summary>
        /// Operationskontrakt för modifiering av befintlig förrättare
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="minister">Förrättaren (<see cref="Minister"/>) som ska uppdateras.</param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void UpdateMinister(User user, Minister minister);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ceremony"></param>
        /// <param name="ticketId"></param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void UpdateCeremony(User user, Ceremony ceremony, int ticketId);

        /// <summary>
        /// Operationskontrakt för att lägga till en ny förrättare
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="minister">Förrättaren (<see cref="Minister"/>) som ska uppdateras.</param>
        /// <returns>Det erhållna förrättarid-numret.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        int AddMinister(User user, Minister minister);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ministerId"></param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        Minister GetMinister(User user, int ministerId);

        /// <summary>
        /// Operationskontraktet som hämtar alla förrättare
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista med förrättare <see cref="Minister"/> eller en tom lista om inga förrättare finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<Minister> GetMinisters(User user);

        /// <summary>
        /// Operationskontraktet som hämtar alla förrättare med verksamhetsperiod inom angivet datum.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="date">Det datum då förrättaren ska vara verksam.</param>
        /// <returns>En lista med förrättare <see cref="Minister"/> som är verksamma inom den givna perioden eller en tom lista om inga förrättare finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<Minister> GetMinistersForPeriod(User user, DateTime date);

        /// <summary>
        /// Operationskontraktet som hämtar alla tidsblock.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista med tidsblock <see cref="MinisterTimeBlock"/> som är verksamma inom den givna perioden eller en 
        /// tom lista om inga förrättare finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<MinisterTimeBlock> GetTimeBlocks(User user);

        /// <summary>
        /// Operationskontraktet som uppdaterar alla tidsblock, om inte tidsblocket finns så läggs det till. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="timeBlocks">En lista med tidsblock (<see cref="MinisterTimeBlock"/>) som ska läggas till.</param>
        /// <returns>En lista med de uppdaterade tidsblocken <see cref="MinisterTimeBlock"/> som är verksamma inom den givna perioden eller en 
        /// tom lista om inga förrättare finns.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<MinisterTimeBlock> UpdateTimeBlocks(User user, List<MinisterTimeBlock> timeBlocks);

        /// <summary>
        /// Operationskontraktet som hämtar tidsblock för ett givet datum. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="date">Det datum för vilka tidsblock (<see cref="MinisterTimeBlock"/>) ska hämtas.</param>
        /// <returns>En lista med de aktuella tidsblocken <see cref="MinisterTimeBlock"/>.</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<MinisterTimeBlock> GetTimeBlocksForDate(User user, DateTime date);

        /// <summary>
        /// Operationskontrakt för att hämta tidsblock för en förrättare. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ministerId">Id på den förrättare som tider ska hämtas för. </param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        List<MinisterTimeBlock> GetTimeBlocksForMinister(User user, int ministerId);

        /// <summary>
        /// Operationskontrakt för att lägga till en användare. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="ParvisUser"/>).</param>
        /// <param name="addedUser">Användarinformation om den nya användaren</param>
        /// <returns>Id-numret på den tillagda användaren. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        int AddUser(User user, ParvisUser addedUser);

        /// <summary>
        /// Autentisering av användare mot systemet. 
        /// </summary>
        /// <param name="user">Användaren som försöker logga in. </param>
        /// <returns>Behörig användare med dess roll, annars null. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        User Login(User user);
        
        /// <summary>
        /// Avaktiverar en användare i systemet. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="username">Den användare som ska avaktiveras. </param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void SetUserInactive(User user, string username);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="updatedUser"></param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void UpdateUser(User user, ParvisUser updatedUser);

        /// <summary>
        /// Hämta alla användare i systemet. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="includeInactiveUsers">Inludera inaktiva användare. </param>
        /// <returns>En lista med användare (<see cref="ParvisUser"/>).</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        List<ParvisUser> GetUsers(User user, bool includeInactiveUsers);

        /// <summary>
        /// Hämtar en användare i systemet. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="parvisUserId">Användarens id. </param>
        /// <returns>Användaren (<see cref="ParvisUser"/>).</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        ParvisUser GetParvisUser(User user, int parvisUserId);

        /// <summary>
        /// Hämtar alla användarroller. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista med alla roller. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        List<UserRole> GetRoles(User user);

        /// <summary>
        /// Sparar en bokning till ett befintligt ärende
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ticketId">Nyckeln på det ärende som avses. </param>
        /// <param name="booking">Den bokning (<see cref="Booking"/>) som ska sparas. </param>
        /// <returns>Bokningen, eller null om ingen bokning finns. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void SaveBooking(User user, int ticketId, Booking booking);

        /// <summary>
        /// Avbokar en befintlig bokning för ett ärende
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ticketId">Nyckeln på det ärende som avses. </param>
        /// <returns>Bokningen, eller null om ingen bokning finns. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void CancelBooking(User user, int ticketId);

        /// <summary>
        /// Hämtar en bokning för ett aktuellt ärende
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ticketId">Nyckeln på det ärende som avses. </param>
        /// <returns>Bokningen, eller null om ingen bokning finns. </returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        Booking GetBooking(User user, int ticketId);

        /// <summary>
        /// Hämtar historiken för ett ärende
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ticketId">Ärendet som historiken som hämtas för. </param>
        /// <returns>En lista med historik (<see cref="History"/>).</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<History> GetHistory(User user, int ticketId);

        /// <summary>
        /// Hämtar alla lediga tidsblock
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En lista med lediga tidsblock</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        IList<TimeBlock> GetFreeTimeBlocks(User user);

        /// <summary>
        /// Hämtar information om ceremoni för ett visst ärende. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="ticketId">Ärende-numret för den ceremoniinformation som ska hämtas</param>
        /// <returns>Ceremoniinformationen (<see cref="CeremonyBooking"/>).</returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        CeremonyBooking GetCeremony(User user, int ticketId);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="coupleId"></param>
        /// <param name="ticketStatusType"></param>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        void UpdateTicketStatus(User user, int coupleId, TicketStatusType ticketStatusType);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ministerId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(StockholmStadApplicationErrorFault))]
        [FaultContract(typeof(StockholmStadSystemErrorFault))]
        bool HasMinisterAnyServices(User user, int ministerId, DateTime date);
    }
}